package cn.display.pixelworksx7.util

import android.content.Context
import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.os.Vibrator
import android.util.Log
import cn.display.pixelworksx7.MainActivity
import cn.display.pixelworksx7.constant.GlobalData
import cn.display.pixelworksx7.data.AppConfigInfoFile
import cn.display.pixelworksx7.threadpool.SystemThreadPool
import org.w3c.dom.Document
import org.w3c.dom.Element
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.util.*
import java.util.stream.Collectors
import javax.xml.parsers.DocumentBuilder
import javax.xml.parsers.DocumentBuilderFactory
import javax.xml.transform.OutputKeys
import javax.xml.transform.Transformer
import javax.xml.transform.TransformerFactory
import javax.xml.transform.dom.DOMSource
import javax.xml.transform.stream.StreamResult
import kotlin.streams.toList

class IrisConfigUtil {
    companion object {
        val TAG = "IrisConfigUtil"
        // 配置文件路径
        var irisConfigFilePath = "/sdcard/pixelworksx7.xml"
        var irisConfigBinFilePath = "/odm/bin/irisConfig"
        var touchConfigBinFilePath = "/odm/bin/touchHidlTest"
        val irisConfigListId = "feature_config_list"

        // 获取本机第三方软件
        fun getAppInfoList(packageManager: PackageManager): MutableList<PackageInfo> {
            var applicationInfoList = mutableListOf<PackageInfo>()
            if (!GlobalData.isShowSystemApp) {
                applicationInfoList = packageManager.getInstalledPackages(0)
                    .stream()
                    // 过滤掉系统软件
                    .filter { (it.applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM) <= 0 }
                    .toList() as MutableList<PackageInfo>
            } else {
                applicationInfoList = packageManager.getInstalledPackages(0)
                    .stream()
                    // 过滤掉第三方应用
                    .filter { (it.applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM) == ApplicationInfo.FLAG_SYSTEM }
                    .toList() as MutableList<PackageInfo>
            }
            return applicationInfoList
        }
        fun drawableToBitmap(drawable: Drawable): Bitmap {
            // 首先检查 drawable 是否为 BitmapDrawable
            if (drawable is BitmapDrawable) {
                return drawable.bitmap
            }

            // 如果不是，创建一个新的 Bitmap 对象，并在 Canvas 上绘制 Drawable
            val bitmap = Bitmap.createBitmap(
                drawable.intrinsicWidth,
                drawable.intrinsicHeight,
                Bitmap.Config.ARGB_8888
            )
            val canvas = Canvas(bitmap)
            drawable.setBounds(0, 0, canvas.width, canvas.height)
            drawable.draw(canvas)
            return bitmap
        }
        //  禁用iris
        fun disableIris() {
            if (GlobalData.isOpenIrisConfig) {
                ShellUtil.execCommand(GlobalData.disableIrisCommands, true)
                ShellUtil.execCommand(GlobalData.touchModeShell.get("120"),true)
                GlobalData.isOpenIrisConfig = false
            }
        }
        fun executeAppIrisConfig(packageName: String) {
            val topPackageName = ShellUtil.execCommand(
                "dumpsys activity activities|grep topResumedActivity=|tail -n 1|cut -d \"{\" -f2|cut -d \"/\" -f1|cut -d \" \" -f3",
                true
            ).successMsg
            if (packageName.equals(topPackageName)) {
                // disableIris()
                if (GlobalData.irisConfigMap.containsKey(topPackageName)) {
                    // 有配置
                    val paramsCommandList = GlobalData.irisConfigMap[topPackageName]!!.stream()
                        .map { it: String -> irisConfigBinFilePath + " " + it }
                        .collect(Collectors.toList())
                    if (paramsCommandList != null) {
                        ShellUtil.execCommand(paramsCommandList.toTypedArray(), true)
                    }
                    GlobalData.isOpenIrisConfig = true
                }
                if (GlobalData.touchConfigMap.containsKey(topPackageName)) {
                    Log.d("TAG", topPackageName + ":{" + "touchHz:" + GlobalData.touchConfigMap[topPackageName] + "}")
                    // 有配置
                    val touchHz = GlobalData.touchConfigMap[topPackageName]
                    ShellUtil.execCommand(GlobalData.touchModeShell[touchHz], true)
                }
                GlobalData.lastTopPackageName = packageName
            }
              //  val pattern = longArrayOf(0, 200, 100, 500) // 0表示开始震动，100毫秒震动，100毫秒停止，100毫秒震动
          // GlobalData.vibrator?.vibrate(pattern, -1) // -1表示无限重复
        }

        fun clearConfigByPackageName(packageName: String) {
            val topPackageName = ShellUtil.execCommand(
                "dumpsys activity activities|grep topResumedActivity=|tail -n 1|cut -d \"{\" -f2|cut -d \"/\" -f1|cut -d \" \" -f3",
                true
            ).successMsg
            if (packageName.equals(topPackageName)) {
                disableIris()
            }
            var document = getIrisConfigFileDocument()
            var ids = mutableListOf<String>(packageName, "touch." + packageName)
            val irisConfigListE: Element = getIrisConfigListElement(document)
            for (id in ids) {
                var node = document.getElementById(id)
                if (node != null) {
                    irisConfigListE.removeChild(node)
                }
            }
            documentWriteIrisConfigFile(document)
            loadIrisConfigFileParseToMap()
        }

        // 添加配置
        fun addIrisConfig(appConfigInfo: AppConfigInfoFile): Int {
            Log.e(TAG, "appConfigInfo" + appConfigInfo.toString())
            var document = getIrisConfigFileDocument()
            // 获取子节点
            var irisConfigNode = document.getElementById(appConfigInfo.packageName)
            var params = appConfigInfo.params
            val irisConfigListE: Element = getIrisConfigListElement(document)
//            if (irisConfigNode != null) {
//                // 先获取文件里的参数
//                // 删除配置
//                Log.e(TAG, "nodeValue" + irisConfigNode.nodeValue)
//                val paramsNodes = irisConfigNode.getElementsByTagName("params")
//                // irisConfigListE.removeChild(irisConfigNode)
//                for (index in 0..params.size - 1) {
//                    paramsNodes.item(index).textContent = params.get(index)
//                }
//            } else {
                if (params.size != 0) {
                    irisConfigNode = document.createElement("iris_config")
                    irisConfigNode.setAttribute("id", appConfigInfo.packageName)
                    irisConfigNode.setAttribute("create_time", DateUtil.formatDate(Date()))
                    // 设置参数
                    for (index in 0..params.size - 1) {
                        val irisConfigParamsE: Element = document.createElement("params")
                        irisConfigParamsE.textContent = params.get(index)
                        irisConfigNode.appendChild(irisConfigParamsE)
                    }
                    irisConfigListE.appendChild(irisConfigNode)
                }
//            }
            documentWriteIrisConfigFile(document)
            loadIrisConfigFileParseToMap()
            executeAppIrisConfig(appConfigInfo.packageName)
            return 1
        }

        fun addTouchConfig(packageName: String, touchMode: String) {
            var document = getIrisConfigFileDocument()
            // 获取子节点
            var touchConfigNode = document.getElementById("touch." + packageName)
            if (touchConfigNode == null && touchMode.equals("120")) {
                return
            }
            if (touchConfigNode != null && touchConfigNode.childNodes.item(1).textContent.equals(touchMode)) {
                return
            }
            val irisConfigListE: Element = getIrisConfigListElement(document)
//            if (touchConfigNode != null) {
//                touchConfigNode.childNodes.item(1).textContent = touchMode
//            } else {
                touchConfigNode = document.createElement("touch_config")
                touchConfigNode.setAttribute("id", "touch." + packageName)
                touchConfigNode.setAttribute("create_time", DateUtil.formatDate(Date()))
                val touchConfigParam: Element = document.createElement("param")
                touchConfigParam.textContent = touchMode
                touchConfigNode.appendChild(touchConfigParam)
                irisConfigListE.appendChild(touchConfigNode)
//            }
            documentWriteIrisConfigFile(document)
            loadIrisConfigFileParseToMap()
        }

        // init irisConfig file
        private fun initIrisConfigFile() {
            // 创建文档构建工厂
            val documentBuilderFactory: DocumentBuilderFactory = DocumentBuilderFactory.newInstance()
            // 创建文档构建
            var documentBuilder: DocumentBuilder? = null
            documentBuilder = documentBuilderFactory.newDocumentBuilder()
            // 先获取文档
            val document: Document = documentBuilder.newDocument()
            document.setXmlStandalone(true)
            document.setXmlVersion("1.0")
            // 根节点
            val irisConfigListE: Element = document.createElement(irisConfigListId)
            irisConfigListE.setAttribute("id", irisConfigListId)
            document.appendChild(irisConfigListE)
            documentWriteIrisConfigFile(document)
        }

        // reset irisConfig file
        fun resetIrisConfigFile() {
            File(irisConfigFilePath).delete()
            initIrisConfigFile()
        }

        // 读取文件配置解析成map
        fun loadIrisConfigFileParseToMap() {
            var exists = File(irisConfigFilePath).exists()
            if (!exists) {
                initIrisConfigFile()
            }
            var document = getIrisConfigFileDocument()
            SystemThreadPool.getExecutorService().execute(Runnable {
                val irisConfigMap: MutableMap<String, List<String>> = mutableMapOf()
                var irisConfigChildNodes = document.getElementsByTagName("iris_config")
                for (childNodesIndex in 0..irisConfigChildNodes.length - 1) {
                    var paramsList = mutableListOf<String>()
                    var irisConfigNode = irisConfigChildNodes.item(childNodesIndex)
                    var attributes = irisConfigNode.attributes
                    var paramsNodes = irisConfigNode.childNodes
                    for (paramsNodesIndex in 0..paramsNodes.length - 1) {
                        var textContent = paramsNodes.item(paramsNodesIndex).textContent
                        if (!textContent.trim().equals("")) {
                            paramsList.add(textContent)
                        }
                    }
                    var packageName = ""
                    for (attributesIndex in 0..attributes.length - 1) {
                        val attribute = attributes.item(attributesIndex)
                        if (attribute.nodeName.equals("id")) {
                            packageName = attribute.nodeValue
                            break
                        }
                    }
                    irisConfigMap.put(packageName, paramsList)
                }
                GlobalData.irisConfigMap = irisConfigMap
            })
            SystemThreadPool.getExecutorService().execute(Runnable {
                val touchConfigMap: MutableMap<String, String> = mutableMapOf()
                var touchConfigChildNodes = document.getElementsByTagName("touch_config")
                for (childNodesIndex in 0..touchConfigChildNodes.length - 1) {
                    var touchConfigNode = touchConfigChildNodes.item(childNodesIndex)
                    var attributes = touchConfigNode.attributes
                    var packageName = ""
                    for (attributesIndex in 0..attributes.length - 1) {
                        val attribute = attributes.item(attributesIndex)
                        if (attribute.nodeName.equals("id")) {
                            packageName = attribute.nodeValue.replace("touch.", "")
                            break
                        }
                    }
                    touchConfigMap.put(packageName, touchConfigNode.childNodes.item(1).textContent)
                }
                GlobalData.touchConfigMap = touchConfigMap
            })
        }

        // val irisConfigListE: Element =
        fun getIrisConfigListElement(document: Document): Element {
            return document.getElementById(irisConfigListId)
        }

        fun getIrisConfigFileDocument(): Document {
            // 创建文档构建工厂
            val documentBuilderFactory: DocumentBuilderFactory = DocumentBuilderFactory.newInstance()
            // 创建文档构建
            var documentBuilder: DocumentBuilder? = null
            documentBuilder = documentBuilderFactory.newDocumentBuilder()
            // 先获取文档
            try {
                val document: Document = documentBuilder.parse(File(irisConfigFilePath))
                return document
            } catch (e: Exception) {
                try {
//                    initIrisConfigFile()
                    val document: Document = documentBuilder.parse(File(irisConfigFilePath))
                    return document
                } catch (e: Exception) {
                    return documentBuilder.parse(File(irisConfigFilePath))
                }
            }
        }

        // 文档写入到文件
        fun documentWriteIrisConfigFile(document: Document) {
            var tff: TransformerFactory = TransformerFactory.newInstance();
            // 创建一个Transformer的对象
            var tf: Transformer = tff.newTransformer();
            // 输出内容是否使用换行
            tf.setOutputProperty(OutputKeys.INDENT, "yes");
            // 创建xml文件并写入内容
            tf.transform(DOMSource(document), StreamResult(File(irisConfigFilePath)));
        }

        // 通过包名获取其参数
        fun getIrisConfigByPackageName(packageName: String): List<String> {
            var paramsList = mutableListOf<String>()
            var irisCOnfigFileDocument = getIrisConfigFileDocument()
            var irisConfigElement = irisCOnfigFileDocument.getElementById(packageName)
            // 没有对应的参数
            if (irisConfigElement == null) {
                return paramsList
            }
            var paramsNodes = irisConfigElement.getElementsByTagName("params")
            for (paramsNodesIndex in 0..paramsNodes.length - 1) {
                val paramsNode = paramsNodes.item(paramsNodesIndex)
                paramsList.add(paramsNode.textContent)
            }
            return paramsList
        }
    }
}
